package com.example.springtask.config;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.partition.PartitionHandler;
import org.springframework.batch.core.partition.support.Partitioner;
import org.springframework.batch.core.partition.support.SimplePartitioner;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.data.RepositoryItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.deployer.resource.maven.MavenResource;
import org.springframework.cloud.deployer.spi.task.TaskLauncher;
import org.springframework.cloud.task.batch.partition.DeployerPartitionHandler;
import org.springframework.cloud.task.batch.partition.PassThroughCommandLineArgsProvider;
import org.springframework.cloud.task.batch.partition.SimpleEnvironmentVariablesProvider;
import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.cloud.task.repository.TaskRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@Profile("!worker")
@Configuration
@EnableTask
@EnableBatchProcessing
public class ManageConfiguration {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Autowired
    private Environment environment;

    @Autowired
    private ResourceLoader resourceLoader;

    @Bean
    public Job partitionedJob() throws Exception {
        Random random = new Random();
        return this.jobBuilderFactory.get("partitionedJob" + random.nextInt())
                .start(step1())
                .listener(new JobExecutionListener() {
                    @Override
                    public void beforeJob(JobExecution jobExecution) {

                    }

                    @Override
                    public void afterJob(JobExecution jobExecution) {
                        System.out.println("执行结果：" + jobExecution.getStatus());
                    }
                })
                .build();
    }

    @Bean
    public Step step1() throws Exception {
        return this.stepBuilderFactory.get("step1")
                .partitioner("workerStep", partitioner())
                .partitionHandler(partitionHandler(null,  null, null))
                .build();
    }

    @Bean
    public PartitionHandler partitionHandler(TaskLauncher taskLauncher, JobExplorer jobExplorer, TaskRepository taskRepository) throws Exception {
        Resource resource = resourceLoader.getResource("file://C:/Users/linxiaoqing/Downloads/springtask/target/springtask-0.0.1-SNAPSHOT.jar");

//        @see https://github.com/spring-cloud/spring-cloud-deployer/tree/main/spring-cloud-deployer-resource-docker
//        Resource resource = resourceLoader.getResource("docker:springcloud/app-name:tag")

//        @see https://github.com/spring-cloud/spring-cloud-deployer/tree/main/spring-cloud-deployer-resource-maven
//        Resource resource = resourceLoader.getResource("maven://group:artifact:version")

        DeployerPartitionHandler partitionHandler = new DeployerPartitionHandler(
                taskLauncher, jobExplorer, resource, "workerStep", taskRepository
        );
        List<String> commandLineArgs = new ArrayList<>(3);
        commandLineArgs.add("--spring.profiles.active=worker");
        commandLineArgs.add("--spring.cloud.task.initialize-enabled=false");
        commandLineArgs.add("--spring.batch.jdbc.initialize-schema=never");
        partitionHandler.setCommandLineArgsProvider(new PassThroughCommandLineArgsProvider(commandLineArgs));
        partitionHandler.setEnvironmentVariablesProvider(new SimpleEnvironmentVariablesProvider(this.environment));
        partitionHandler.setApplicationName("WorkerJob");
        partitionHandler.setMaxWorkers(2);
        partitionHandler.setGridSize(2); //10个任务
        return partitionHandler;
    }

    public Partitioner partitioner() {
//        return new Partitioner() {
//            @Override
//            public Map<String, ExecutionContext> partition(int gridSize) {
//                Map<String, ExecutionContext> partitions = new HashMap<>(gridSize);
//                for (int i = 0; i < gridSize; i++) {
//                    ExecutionContext executionContext = new ExecutionContext();
//                    executionContext.put("partitionNumber", i);
//                    partitions.put("partition" + i, executionContext);
//                }
//                return partitions;
//            }
//        };
        return new SimplePartitioner();
    }

}
